// 
//  FDApplication.m
//  FiveDice
//  
//  Created by Chris Born.
//  Copyright 2007 Borngraphics. All rights reserved.
//  
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or any later version.
//  
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//  
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//  
//  By contributing code you grant Chris Born and Borngraphics an
//  unlimited, non-exclusive license to your contribution.
//  
//  For support, questions, commercial use, etc...
//  E-Mail: chris <at> borngraphics <dot> com
// 

#import "FDApplication.h"

@implementation FDApplication
- (id)init
{
	if(self = [super init])
	{
		// Application Initialized
	}
	return self;
}

#pragma mark Application Launch and Suspend
- (void)applicationDidFinishLaunching:(id)unused
{
	NSLog(@"%s", _cmd);
	
	_contentRect = [UIHardware fullScreenApplicationContentRect];
	_contentRect.origin.x = 0.0f;
	_contentRect.origin.y = 0.0f;
	
	defaults = [[FDDefaultsController alloc] init];
	mainWindow = [[UIWindow alloc] initWithContentRect:[UIHardware fullScreenApplicationContentRect]];
	mainView = [[UIView alloc] initWithFrame:_contentRect];
	
	UIImageView	*background = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, _contentRect.size.width, _contentRect.size.height)];
	[background setImage:[UIImage applicationImageNamed:@"greenfelt.png"]];	
	[mainView addSubview:background];
	[background release];
	
	navBar = [[UINavigationBar alloc] init];
	[navBar setFrame:CGRectMake(_contentRect.origin.x, _contentRect.origin.y, _contentRect.size.width, 45.0f)];
	[navBar setBarStyle:1];
	[navBar setImage:[UIImage applicationImageNamed:@"navbar.png"]];
	
	[navBar setDelegate:self];
	[navBar enableAnimation];
	
	navBarTitle = [[UINavigationItem alloc] init];
	[navBar pushNavigationItem:navBarTitle];
	
	[mainView addSubview:navBar];
	
	[mainWindow setContentView:mainView];
	
	[mainWindow orderFront:self];
	[mainWindow makeKey:self];
	[mainWindow _setHidden:NO];
	
	// Get a MenuView and a GameView and place them off screen
	gameMenuView = [[FDGameMenuView alloc] initWithFrame:CGRectMake(_contentRect.origin.x - _contentRect.size.width,
		_contentRect.origin.y + 45.0f,
		_contentRect.size.width,
		_contentRect.size.height - 45.0f)];
	[gameMenuView setDelegate:self];
	[mainView addSubview:gameMenuView];
		
	gameView = [[FDGameView alloc] initWithFrame:CGRectMake(_contentRect.origin.x + _contentRect.size.width,
		_contentRect.origin.y + 45.0f,
		_contentRect.size.width,
		_contentRect.size.height - 45.0f)];
	[gameView setDelegate:self];
	[mainView addSubview:gameView];
	
	[self setCurrentState:[[NSUserDefaults standardUserDefaults] integerForKey:@"SavedState"]];
	[self finishUserInterfaceForState:[self currentState]];
	
	
	/*
		This is my approach to showing an about alert at launch time only if this is the first launch of a version.
		By storing the current version in the prefs file, we can do several things. One is bellow, where it is compared
		with the version of the app as identified in the Info.plist.
	*/
	NSString *version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
	if (![[defaults version] isEqualToString:version]) {
		[self showAboutAlert];
		[defaults setVersion:version];
	}
}

- (void)applicationWillSuspend
{
	/*
		We always want to set the current state when we leave, but only save the game if we are in a game.
		This speeds up closing out, when game position info is not needed.
	*/
	[defaults setSavedState:[self currentState]];
	if ([self currentState] == INGAME) [self saveGamePosition];
}

#pragma mark Persistence Methods

- (void)saveGamePosition
{
	[defaults setRollCount:[gameView rollCount]];
	[defaults setLastRoll:[gameView lastRoll]];
	[defaults setTurnCount:[gameView turnCount]];
	[defaults setDiceTotal:[gameView diceTotal]];
	[defaults setWildcard:[gameView wildcard]];
	[defaults setYahtzeeCount:[gameView yahtzeeCount]];
	[defaults setSelectedRow:[gameView selectedRow]];
	[defaults setLastSelectedRow:[gameView lastScore]];
	
	[defaults setDiceValues:[gameView pDiceValues]];
	[defaults setScores:[gameView scoreCardScores]];
	[defaults setScoresSet:[gameView scoreCardSetScores]];
	[defaults synchronize];
}

#pragma mark Handle Current State

// This will finish loading the views based on the saved game state
- (void)finishUserInterfaceForState:(int)state
{
	NSLog(@"%s Current State: %i", _cmd, state);
	switch (state) {
		case NEWGAME:
		[self startNewGame];
		break;
		case INGAME:
		[self continueLastGameWithOver:NO];
		break;
		case GAMEOVER:
		[self continueLastGameWithOver:YES];
		break;
		default:
		[self showGameMenu];
	}
}

#pragma mark Show and Hide Views

- (void)showGameMenu
{
	NSLog(@"%s", _cmd);
	if ([self currentState] == INGAME || [self currentState] == NEWGAME || [self currentState] == GAMEOVER) [gameView hide];
	[self changeStateTo:MENU];
	// This timer gives the score card a chance to start hiding before we slide things out
	NSTimer		*animDelay = [NSTimer scheduledTimerWithTimeInterval:0.2
										  	  target:self
											selector:@selector(showGameMenuAfterDelay:)
											userInfo:nil
										 	 repeats:NO];
}

- (void)showGameMenuAfterDelay:(NSTimer *)aTimer
{
	[aTimer invalidate];
	[gameMenuView show];
}

- (void)showGameView
{
	NSLog(@"%s", _cmd);
	if ([self currentState] == MENU) [gameMenuView hide];
	[gameView show];
	[self changeStateTo:INGAME];
}

- (void)waitForNewGameSetup:(NSTimer *)aTimer
{
	[aTimer invalidate];
	[self showGameView];
	[self changeStateTo:NEWGAME];
}

- (void)startNewGame // Also used as a delegate for GameMenu Button
{
	NSLog(@"%s", _cmd);
	[gameView newGame];
	
	// This timer creates a small dealy so the new game stuff finishes before we swap the views in
	NSTimer		*newGameDelay = [NSTimer scheduledTimerWithTimeInterval:0.2
										  	  target:self
											selector:@selector(waitForNewGameSetup:)
											userInfo:nil
										 	 repeats:NO];
}

- (void)continueLastGameWithOver:(BOOL)over
{
	NSLog(@"%s", _cmd);

	[gameView setRollCount:[defaults rollCount]];
	[gameView setLastRoll:[defaults lastRoll]];
	[gameView setTurnCount:[defaults turnCount]];
	[gameView setDiceTotal:[defaults diceTotal]];
	[gameView setWildcard:[defaults wildcard]];
	[gameView setYahtzeeCount:[defaults yahtzeeCount]];
	[gameView setSelectedRow:[defaults selectedRow]];
	[gameView setLastScore:[defaults lastSelectedRow]];

	[gameView loadSavedGame];
	
	[self setPlaying:YES];
	
	[self updateRollButtonWithLast:NO];
	[self showGameView];
}

- (void)showAboutAlert
{
	UIAlertSheet	*donateSheet = [[UIAlertSheet alloc] initWithFrame:CGRectMake(0,240,320,240)];
	[donateSheet setTitle:[NSString stringWithFormat:@"FiveDice v.%@",[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]];
	[donateSheet setContext:@"about"];
	[donateSheet setBodyText:@"Five Dice is a clone of the popular family game Yahtzee. Rules and a change log may be found at 5dice.googlecode.com.\n\nMany hours went into developing and improving this game. If you enjoy playing it, please consider sending a few bucks via PayPal to chris@borngraphics.com.\n\nThank You!"];
	[donateSheet addButtonWithTitle:@"Ok"];
	[donateSheet addButtonWithTitle:@"Vist PayPal"];
	[donateSheet setDelegate: self];
	[donateSheet presentSheetInView:mainView];
}

#pragma mark Notification and Delegate Responders

- (void)scoreCardSelectionChanged:(NSNotification *)notification
{
	NSLog(@"%s", _cmd);
}

- (void)rolledYahtzee:(NSNotification *)notification
{
	NSLog(@"%s", _cmd);
}

- (void)updateRollButtonWithLast:(BOOL)withLast {
	// NSLog(@"%s Current roll value: %i", _cmd, [gameView rollCount]+1);
	// NSLog(@"%s Last roll value: %i", _cmd, [gameView lastRoll]+1);
	if ([gameView rollCount] < 3 ) {
		if (withLast) {
			[self setNavBarLeftButton:@"Menu" withStyle:2 rightButton:[NSString stringWithFormat:@"Roll %i of 3",[gameView lastRoll]+1] withStyle:1];
		} else {
			[self setNavBarLeftButton:@"Menu" withStyle:2 rightButton:[NSString stringWithFormat:@"Roll %i of 3",[gameView rollCount]+1] withStyle:1];
		}
	} else {
		// NSLog(@"%s Count is >= 3", _cmd);
		[self setNavBarLeftButton:@"Menu" withStyle:2 rightButton:nil withStyle:0];
	}
}

- (void)changeStateTo:(int)state
{
	NSLog(@"%s to: %i with previous state: %i", _cmd,state,[self previousState]);
	if ([self currentState] == GAMEOVER) {
		[self setPreviousState:[self currentState]];
	} else if ([self previousState] != INGAME || [self previousState] != GAMEOVER) {
		[self setPreviousState:currentState]; // This prevents not being able to get back to current game
	}
	
	[self setCurrentState:state];
	
	switch (state) {
		case HIGHSCORES:
		[self setNavBarLeftButton:@"Menu" withStyle:2 rightButton:@"Clear" withStyle:1];
		break;
		case MENU:
		[navBarTitle setTitle:@""];
		if ([self previousState] == INGAME || [self playing]) {
			[self setNavBarLeftButton:@"Keep Playing" withStyle:2 rightButton:@"High Scores" withStyle:0];
		} else {
			[self setNavBarLeftButton:nil withStyle:2 rightButton:@"High Scores" withStyle:0];
		}
		break;
		case GAMEOVER:
		[self setNavBarLeftButton:@"New Game" withStyle:2 rightButton:nil withStyle:0];
		[self setPlaying:NO];
		break;
		case INGAME:
		[navBarTitle setTitle:[defaults playerOneName]];
		[self updateRollButtonWithLast:NO];
		//[self setNavBarLeftButton:@"Menu" withStyle:2 rightButton:[NSString stringWithFormat:@"Roll %i of 3",[gameView lastRoll]+1] withStyle:1];
		break;
		case NEWGAME:
		[navBarTitle setTitle:[defaults playerOneName]];
		[self setPlaying:YES];
		//[self setNavBarLeftButton:@"Menu" withStyle:2 rightButton:[NSString stringWithFormat:@"Roll %i of 3",[gameView lastRoll]+1] withStyle:1];
		break;
		default:
		[self setNavBarLeftButton:@"Menu" withStyle:2 rightButton:nil withStyle:0];
	}
}

#pragma mark Button delegates

- (void)navigationBar:(UINavigationBar*)bar buttonClicked:(int)button
{
	if (button == 1) {
		NSLog(@"%s Clicked Left Button", _cmd);
		switch ([self currentState]) {
			case HIGHSCORES:
			[gameMenuView hideHighScoresBanner];
			break;
			case MENU:
			[self showGameView];
			[self setCurrentState:INGAME];
			break;
			case INGAME:
			[self showGameMenu];
			break;
			case NEWGAME:
			[self showGameMenu];
			break;
			case GAMEOVER:
			[self showGameMenu];
			break;
		}
		
	} else if (button == 0) {
		NSLog(@"%s Clicked Right Button", _cmd);
		switch ([self currentState]) {
			case HIGHSCORES:
			[self sendAlertWithContext:@"clearhighscores"];
			break;
			case MENU:
			[gameMenuView showHighScoresBanner];
			break;
			case INGAME:
			// Roll
			[gameView rollDice];
			break;
			case NEWGAME:
			// Roll
			[gameView rollDice];
			break;
			case GAMEOVER:
			// nil
			break;
		}
	}
}

#pragma mark Alert Sheet
- (void)sendAlertWithContext:(NSString *)context {
	NSLog(@"%s", _cmd);
	NSString *titleText;
	NSString *bodyText;

	titleText = [NSString stringWithFormat:@"Clear High Scores!"];
	bodyText = [NSString stringWithFormat:@"You are about to clear your high scores. There is no turning back."];

	UIAlertSheet	*alertSheet = [[UIAlertSheet alloc] initWithFrame:CGRectMake(0,240,320,240)];
	[alertSheet setTitle:titleText];
	[alertSheet setContext:context];
	[alertSheet setBodyText:bodyText];
	[alertSheet addButtonWithTitle:@"Ok"];
	[alertSheet addButtonWithTitle:@"Cancel"];
	[alertSheet setDelegate: self];
	[alertSheet popupAlertAnimated:YES];
}

- (void)alertSheet:(UIAlertSheet *)sheet buttonClicked:(int)button {
	if ([[sheet context] isEqualToString:@"clearhighscores"]) {
		if (button == 1) {
			[defaults clearHighScores];
			[gameMenuView sendClearHighScores];
		}
	} else if ([[sheet context] isEqualToString:@"about"]) {
		if (button == 2) {
			/*
				This is just a paypal generated donate link using the email link url provided from their site.
				You have to the single % signs to doubles when using stringWithFormat
			*/
			NSURL	*payURL = [[NSURL alloc] initFileURLWithPath:[NSString stringWithFormat:@"https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=chris%%40borngraphics%%2ecom&item_name=Five%%20Dice%%2e%%20Because%%20it%%27s%%20fun%%21&buyer_credit_promo_code=&buyer_credit_product_category=&buyer_credit_shipping_method=&buyer_credit_user_address_change=&no_shipping=1&no_note=1&tax=0&currency_code=USD&lc=US&bn=PP%%2dDonationsBF&charset=UTF%%2d8"]];
			[self openURL:payURL];
			[payURL release];
		}
	}
	
	[sheet dismissAnimated:YES];
	[sheet release];
}

#pragma mark Application Accessors
- (void)setNavBarLeftButton:(NSString *)left withStyle:(int)lstyle rightButton:(NSString *)right withStyle:(int)rstyle
{
	[navBar showLeftButton:left withStyle:lstyle rightButton:right withStyle:rstyle];
}

- (void)setNavBarTitle:(NSString *)newTitle
{
	[newTitle retain];
	[title release];
	title = newTitle;
	[navBarTitle setTitle:title];
}

- (int)currentState
{
	return currentState;
}

- (void)setCurrentState:(int)newCurrentState
{	
	currentState = newCurrentState;
}

- (int)previousState
{
	return previousState;
}

- (void)setPreviousState:(int)newPreviousState
{
	previousState = newPreviousState;
}

- (BOOL)playing
{
	return playing;
}

- (void)setPlaying:(BOOL)newPlaying
{
	playing = newPlaying;
}

#pragma mark Dealloc
- (void)dealloc
{
	[gameView release];
	[gameMenuView release];
	[navBarTitle release];
	[navBar release];
	[mainView release];
	[mainWindow release];
	[defaults release];
	[super dealloc];
}

@end